#include <stdlib.h>
#include "loops.h"

struct LoopLabelStack {
    int val ;
    struct LoopLabelStack *next ;
} ;

struct LoopLabelStack *G_StartLabels = NULL ;
struct LoopLabelStack *G_EndLabels = NULL ;

/* Ajoute un label de début / fin de boucle de boucle. */
int pushLoopLabel (int val, enum LoopLabelType type) {
    struct LoopLabelStack *stack ;
    stack = (type == START_LOOP) ? G_StartLabels : G_EndLabels ;
    if (stack == NULL) {
	stack = malloc(sizeof(struct LoopLabelStack)) ;
	stack->next = NULL ;
	stack->val = val ;
    }
    else {
	stack = malloc(sizeof(struct LoopLabelStack)) ;
	stack->val = val ;
	stack->next = (type == START_LOOP) ? G_StartLabels : G_EndLabels ;
    }
    if (type == START_LOOP) {
	G_StartLabels = stack ;
    }
    else {
	G_EndLabels = stack ;
    }
    return 0 ;
}

/* Retourne le label en haut de la pile, ou -1 s'il n'existe pas. */
int getTopLoopLabel (enum LoopLabelType type) {
    struct LoopLabelStack *stack ;
    stack = (type == START_LOOP) ? G_StartLabels : G_EndLabels ;
    if (stack == NULL) {
	return -1 ;
    }
    return stack->val ;
}

/* Pop un label de début / fin de boucle. */
int popLoopLabel (enum LoopLabelType type) {
    struct LoopLabelStack *stack, *aux ;
    int res ;
    stack = (type == START_LOOP) ? G_StartLabels : G_EndLabels ;
    if (stack == NULL) {
	return - 1 ;
    }
    res = stack->val ;
    aux = stack ;
    stack = stack->next ;
    free(aux) ;
    if (type == START_LOOP) {
	G_StartLabels = stack ;
    }
    else {
	G_EndLabels = stack ;
    }
    return res ;
}
